package com.xuedongzhilian.service.impl;

import com.xuedongzhilian.dto.Result;
import com.xuedongzhilian.entity.*;
import com.xuedongzhilian.mapper.*;
import com.xuedongzhilian.service.IRecommendationService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 智能推荐服务实现类
 * </p>
 *
 * @author 学动智联团队
 * @since 2025-10-14
 */
@Service
public class RecommendationServiceImpl implements IRecommendationService {

    @Resource
    private UserInfoExtendMapper userInfoExtendMapper;
    
    @Resource
    private StudyPlanMapper studyPlanMapper;
    
    @Resource
    private RunningRecordMapper runningRecordMapper;
    
    @Resource
    private CheckInMapper checkInMapper;
    
    @Resource
    private WordStudyMapper wordStudyMapper;
    
    @Resource
    private ForumPostMapper forumPostMapper;

    @Override
    public Result getStudyRecommendations(Long userId) {
        // 获取用户扩展信息
        UserInfoExtend userInfo = userInfoExtendMapper.selectById(userId);
        
        // 获取用户最近的学习计划
        List<StudyPlan> recentStudyPlans = studyPlanMapper.selectList(
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<StudyPlan>()
                .eq("user_id", userId)
                .orderByDesc("create_time")
                .last("LIMIT 5")
        );
        
        // 获取用户最近的单词学习记录
        List<WordStudy> recentWordStudies = wordStudyMapper.selectList(
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<WordStudy>()
                .eq("user_id", userId)
                .orderByDesc("last_study_time")
                .last("LIMIT 10")
        );
        
        // 根据用户信息和历史记录生成推荐
        List<String> recommendations = new ArrayList<>();
        
        if (userInfo != null) {
            // 根据学习领域推荐
            if (userInfo.getStudyField() != null && !userInfo.getStudyField().isEmpty()) {
                recommendations.add("推荐您继续学习" + userInfo.getStudyField() + "相关课程");
            }
            
            // 根据学习目标推荐
            if (userInfo.getStudyGoal() != null && !userInfo.getStudyGoal().isEmpty()) {
                recommendations.add("为了实现您的目标\"" + userInfo.getStudyGoal() + "\"，建议制定详细的学习计划");
            }
            
            // 根据学习难度偏好推荐
            if (userInfo.getStudyDifficulty() != null && !userInfo.getStudyDifficulty().isEmpty()) {
                recommendations.add("根据您的学习偏好，推荐选择" + userInfo.getStudyDifficulty() + "难度的学习内容");
            }
        }
        
        // 根据历史学习计划推荐
        if (!recentStudyPlans.isEmpty()) {
            // 分析学习计划完成情况
            long completedPlans = recentStudyPlans.stream()
                .filter(plan -> plan.getStatus() != null && plan.getStatus() == 2)
                .count();
            
            if (completedPlans > 0) {
                recommendations.add("您已完成" + completedPlans + "个学习计划，继续保持良好学习习惯");
            }
            
            // 推荐新的学习计划
            recommendations.add("为您推荐新的学习计划，帮助您持续进步");
        } else {
            recommendations.add("建议您制定第一个学习计划，开启学习之旅");
        }
        
        // 根据单词学习记录推荐
        if (!recentWordStudies.isEmpty()) {
            // 计算掌握率
            long masteredWords = recentWordStudies.stream()
                .filter(word -> word.getIsMastered() != null && word.getIsMastered() == 1)
                .count();
            
            double masteryRate = (double) masteredWords / recentWordStudies.size() * 100;
            recommendations.add("您的单词掌握率为" + String.format("%.1f", masteryRate) + "%，建议继续巩固");
            
            // 推荐未掌握的单词
            long unmasteredWords = recentWordStudies.size() - masteredWords;
            if (unmasteredWords > 0) {
                recommendations.add("您还有" + unmasteredWords + "个单词未掌握，建议重点复习");
            }
        }
        
        return Result.ok(recommendations);
    }

    @Override
    public Result getSportRecommendations(Long userId) {
        // 获取用户扩展信息
        UserInfoExtend userInfo = userInfoExtendMapper.selectById(userId);
        
        // 获取用户最近的跑步记录
        List<RunningRecord> recentRunningRecords = runningRecordMapper.selectList(
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<RunningRecord>()
                .eq("user_id", userId)
                .orderByDesc("create_time")
                .last("LIMIT 5")
        );
        
        // 获取用户最近的运动打卡记录
        List<CheckIn> recentSportCheckIns = checkInMapper.selectList(
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<CheckIn>()
                .eq("user_id", userId)
                .eq("type", 2) // 运动打卡
                .orderByDesc("create_time")
                .last("LIMIT 10")
        );
        
        // 根据用户信息和历史记录生成推荐
        List<String> recommendations = new ArrayList<>();
        
        if (userInfo != null) {
            // 根据身体数据计算BMI并推荐
            if (userInfo.getHeight() != null && userInfo.getHeight() > 0 && 
                userInfo.getWeight() != null && userInfo.getWeight() > 0) {
                double bmi = (double) userInfo.getWeight() / 
                            ((double) userInfo.getHeight() / 100 * (double) userInfo.getHeight() / 100);
                
                if (bmi < 18.5) {
                    recommendations.add("您的BMI为" + String.format("%.1f", bmi) + "，属于偏瘦，建议适当增重并进行力量训练");
                } else if (bmi < 24) {
                    recommendations.add("您的BMI为" + String.format("%.1f", bmi) + "，属于正常范围，继续保持");
                } else if (bmi < 28) {
                    recommendations.add("您的BMI为" + String.format("%.1f", bmi) + "，属于超重，建议有氧运动减脂");
                } else {
                    recommendations.add("您的BMI为" + String.format("%.1f", bmi) + "，属于肥胖，建议制定减重计划");
                }
            }
            
            // 根据运动偏好推荐
            if (userInfo.getSportPreference() != null && !userInfo.getSportPreference().isEmpty()) {
                recommendations.add("根据您的运动偏好，推荐您进行" + userInfo.getSportPreference() + "运动");
            }
            
            // 根据运动强度偏好推荐
            if (userInfo.getSportIntensity() != null && !userInfo.getSportIntensity().isEmpty()) {
                recommendations.add("根据您的运动强度偏好，推荐选择" + userInfo.getSportIntensity() + "强度的运动");
            }
        }
        
        // 根据跑步记录推荐
        if (!recentRunningRecords.isEmpty()) {
            // 计算平均配速
            double totalPace = recentRunningRecords.stream()
                .filter(record -> record.getPace() != null)
                .mapToDouble(record -> record.getPace().doubleValue())
                .sum();
            
            double avgPace = totalPace / recentRunningRecords.size();
            recommendations.add("您的平均配速为" + String.format("%.2f", avgPace) + "分钟/公里");
            
            // 计算总跑步距离
            double totalDistance = recentRunningRecords.stream()
                .filter(record -> record.getDistance() != null)
                .mapToDouble(record -> record.getDistance().doubleValue())
                .sum() / 1000; // 转换为公里
            
            recommendations.add("您最近累计跑步" + String.format("%.2f", totalDistance) + "公里，继续保持");
        } else {
            recommendations.add("建议您开始跑步运动，提升身体素质");
        }
        
        // 根据运动打卡记录推荐
        if (!recentSportCheckIns.isEmpty()) {
            // 计算连续运动天数
            int streak = calculateStreak(recentSportCheckIns);
            if (streak > 0) {
                recommendations.add("您已连续运动" + streak + "天，坚持就是胜利");
            }
        } else {
            recommendations.add("建议您制定运动计划并坚持打卡");
        }
        
        return Result.ok(recommendations);
    }

    @Override
    public Result getContentRecommendations(Long userId) {
        // 获取用户扩展信息
        UserInfoExtend userInfo = userInfoExtendMapper.selectById(userId);
        
        // 获取用户最近的学习打卡记录
        List<CheckIn> recentStudyCheckIns = checkInMapper.selectList(
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<CheckIn>()
                .eq("user_id", userId)
                .eq("type", 1) // 学习打卡
                .orderByDesc("create_time")
                .last("LIMIT 10")
        );
        
        // 获取热门帖子
        List<ForumPost> hotPosts = forumPostMapper.selectList(
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ForumPost>()
                .eq("status", 1) // 正常状态
                .orderByDesc("view_count")
                .last("LIMIT 10")
        );
        
        // 根据用户信息和历史记录生成推荐
        List<Object> recommendations = new ArrayList<>();
        
        if (userInfo != null) {
            // 根据学习领域推荐相关内容
            if (userInfo.getStudyField() != null && !userInfo.getStudyField().isEmpty()) {
                List<ForumPost> relatedPosts = hotPosts.stream()
                    .filter(post -> post.getTitle() != null && 
                           (post.getTitle().contains(userInfo.getStudyField()) || 
                            post.getContent().contains(userInfo.getStudyField())))
                    .collect(Collectors.toList());
                
                recommendations.addAll(relatedPosts);
            }
        }
        
        // 根据学习打卡记录推荐
        if (!recentStudyCheckIns.isEmpty()) {
            // 推荐热门帖子
            recommendations.addAll(hotPosts);
        } else {
            // 推荐新手入门帖子
            List<ForumPost> beginnerPosts = hotPosts.stream()
                .filter(post -> post.getTitle() != null && 
                       (post.getTitle().contains("入门") || 
                        post.getTitle().contains("基础") ||
                        post.getContent().contains("入门") || 
                        post.getContent().contains("基础")))
                .collect(Collectors.toList());
            
            recommendations.addAll(beginnerPosts);
        }
        
        return Result.ok(recommendations);
    }
    
    /**
     * 计算连续打卡天数
     */
    private int calculateStreak(List<CheckIn> checkIns) {
        if (checkIns.isEmpty()) {
            return 0;
        }
        
        // 按日期排序
        List<LocalDate> dates = checkIns.stream()
            .map(CheckIn::getCheckInDate)
            .distinct()
            .sorted()
            .collect(Collectors.toList());
        
        // 计算连续天数
        int streak = 1;
        LocalDate previousDate = dates.get(dates.size() - 1);
        
        for (int i = dates.size() - 2; i >= 0; i--) {
            LocalDate currentDate = dates.get(i);
            if (currentDate.plusDays(1).equals(previousDate)) {
                streak++;
                previousDate = currentDate;
            } else {
                break;
            }
        }
        
        return streak;
    }
}